
package edu.uts.reekie.designer.implementation.edit;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.RotatableDecoration;

import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.editpolicies.ConnectionEditPolicy;
import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
import org.eclipse.gef.requests.GroupRequest;

import edu.uts.reekie.designer.edit.AbstractConnectorEditPart;
import edu.uts.reekie.designer.implementation.figures.CallbackDecoration;
import edu.uts.reekie.designer.implementation.figures.PortDecoration;
import edu.uts.reekie.designer.implementation.model.*;
import edu.uts.reekie.designer.implementation.model.Connector.Style;
import edu.uts.reekie.designer.model.AbstractConnector;


/**
 * Edit part for Connector model elements.
 * <p>This edit part must implement the PropertyChangeListener interface, 
 * so it can be notified of property changes in the corresponding model element.
 * </p>
 * @author Vijay Santhanam
 */
public class ConnectorEditPart extends AbstractConnectorEditPart 
	//implements PropertyChangeListener 
	{
	
	protected void createEditPolicies() {
		
		// Selection handle edit policy. 
		// Makes the connection show a feedback, when selected by the user.
		
		// Allows the removal of the connection model element
		installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectorEditPolicy());
		
	}
	
	private Connector getConnectorModel() {
		return (Connector) getModel();
	}
	
	public IFigure createFigure() {
		IFigure f = super.createFigure();
		try {
			PolylineConnection pc = (PolylineConnection)f;
			applyStyle(pc,getConnectorModel().getStyle());
			
		} catch (Exception ex){}
		
		
		return f;
	}
	 
	public void propertyChange(PropertyChangeEvent event) {
		
		String property = event.getPropertyName();
		if (Connector.PROPERTY_STYLE.equals(property) || Connector.PROPERTY_HAS_PORT.equals(property)) {
			applyStyle((PolylineConnection) getFigure(), getConnectorModel().getStyle());
			refreshVisuals();
		}
		
		super.propertyChange(event);
		
	}
	
	void applyStyle(PolylineConnection c, Style s){
		Connector conn = getConnectorModel();
		boolean isBi = conn.getDirection() == AbstractConnector.BIDIRECTIONAL_CONNECTION;
		boolean hasPort = conn.hasPort();
		RotatableDecoration targetDecoration = null;
		
		switch (s){
		
		case Normal:
			targetDecoration = null;
			//c.setTargetDecoration(new PortDecoration(new PolygonDecoration()));
			c.setSourceDecoration(null);
			c.setLineStyle(Graphics.LINE_SOLID); // always a solid line
			break;
			
		case ApiCall:
			
			targetDecoration = new PolygonDecoration();
			//c.setTargetDecoration(new PolygonDecoration());
			if (isBi){
				c.setSourceDecoration(new PolygonDecoration());
			} else {
				c.setSourceDecoration(null);
			}
			c.setLineStyle(Graphics.LINE_SOLID); // always a solid line
			break;	
			
			
		case Callback:
			
			targetDecoration = new CallbackDecoration();
			//c.setTargetDecoration(new CallbackDecoration());
			if (isBi){
				c.setSourceDecoration(new CallbackDecoration());
			} else {
				c.setSourceDecoration(null);
			}
			c.setLineStyle(Graphics.LINE_SOLID); // strange jazz
			break;
			
		case NetworkProtocol:
			
			targetDecoration = new PolygonDecoration();
			//c.setTargetDecoration(new PolygonDecoration());
			if (isBi){
				c.setSourceDecoration(new PolygonDecoration());
			} else {
				c.setSourceDecoration(null);
			}
			c.setLineStyle(Graphics.LINE_DASH); // dashes
			break;			
			
		case Signal:
			
			targetDecoration = new PolygonDecoration();
			//c.setTargetDecoration(new PolygonDecoration());
			if (isBi){
				c.setSourceDecoration(new PolygonDecoration());
			} else {
				c.setSourceDecoration(null);
			}
			c.setLineStyle(Graphics.LINE_DOT); // dots
			break;			
			
		}
		if (hasPort) {
			c.setTargetDecoration(new PortDecoration(targetDecoration));
		} else {
			c.setTargetDecoration(targetDecoration);
		}
		
	}
	
	
	
	
/*
public void activateFigure(){
	super.activateFigure();
	Once the figure has been added to the ConnectionLayer, start listening for its
	 * router to change.
	 
	getFigure().addPropertyChangeListener(Connection.PROPERTY_CONNECTION_ROUTER, this);
}

public void deactivateFigure(){
	getFigure().removePropertyChangeListener(Connection.PROPERTY_CONNECTION_ROUTER, this);
	super.deactivateFigure();
}
	
*//**
 * Upon activation, attach to the model element as a property change listener.
 *//*
public void activate() {
	if (!isActive()) {
		super.activate();
		getConnectorModel().addPropertyChangeListener(this);
	}
}

 (non-Javadoc)
 * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
 
protected void createEditPolicies() {
	
	// Selection handle edit policy. 
	// Makes the connection show a feedback, when selected by the user.
	installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,new ConnectionEndpointEditPolicy());
	// Allows the removal of the connection model element
	installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectorEditPolicy());
	
}

 (non-Javadoc)
 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
 
protected IFigure createFigure() {
	PolylineConnection connection = (PolylineConnection) super.createFigure();
	
	
	applyDirectionDecorations(connection, getConnectorModel().getDirection());
	connection.setLineStyle(Graphics.LINE_SOLID);  // always a solid line
	
	return connection;
}

*//**
 * Upon deactivation, detach from the model element as a property change listener.
 *//*
public void deactivate() {
	if (isActive()) {
		super.deactivate();
		getConnectorModel().removePropertyChangeListener(this);
	}
}

private Connector getConnectorModel() {
	return (Connector) getModel();
}

 (non-Javadoc)
 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
 
public void propertyChange(PropertyChangeEvent event) {
	String property = event.getPropertyName();
	if (Connector.PROPERTY_DIRECTION.equals(property)) {
		applyDirectionDecorations((PolylineConnection) getFigure(), getConnectorModel().getDirection());
		refreshVisuals();
	}
}

void applyDirectionDecorations(PolylineConnection c, int direction){
	
	c.setTargetDecoration(new PolygonDecoration()); // arrow at target end pt
	if (direction==Connector.BIDIRECTIONAL_CONNECTION){
		c.setSourceDecoration(new PolygonDecoration()); // arrow at source end point
	} else {
		c.setSourceDecoration(null); // arrow at source end point
	}
}*/

}